home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / gcc / ixemlsrc.lha / ixemul / general / getwd.c < prev    next >
C/C++ Source or Header  |  1996-03-13  |  5KB  |  207 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Ray Burr
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. /* Written and Copyright by Ray Burr. 
  21.  * Put under the GNU Library General Public License.
  22.  * Thanks Ray !
  23.  */
  24.  
  25. #define KERNEL
  26. #include "ixemul.h"
  27. #include "kprintf.h"
  28. #include <string.h>
  29.  
  30. #ifndef MAXPATHLEN
  31. #define MAXPATHLEN 1024
  32. #endif
  33.  
  34. /* _GetPathFromLock - Given a pointer to an AmigaDOS Lock structure, build
  35.    a rooted path string in a buffer of a given size.  The buffer should be
  36.    at least 'buffer_length' bytes.  Returns a pointer to the result
  37.    or NULL on an error.  'errno' will be set in the case of an error.  This
  38.    function returns the path string based at 'buffer[0]' but it can alter
  39.    any part of the buffer.  */
  40.  
  41. static char *
  42. _GetPathFromLock (BPTR lock, char *buffer, int buffer_length)
  43. {
  44.   char *p;
  45.   BPTR fl, next_fl;
  46.   int length;
  47.   struct FileInfoBlock *fib;
  48.   int omask;
  49.   char *result = 0;
  50.  
  51.   /* Allocate space on stack for fib. */
  52.  
  53.   BYTE fib_Block[sizeof (struct FileInfoBlock) + 2];
  54.  
  55.   /* Make sure fib is longword aligned. */
  56.  
  57.   fib = (struct FileInfoBlock *) fib_Block;
  58.   if (((ULONG) fib & 0x02) != 0)
  59.     fib = (struct FileInfoBlock *) ((ULONG) fib + 2);
  60.  
  61.   p = 0L;
  62.  
  63.   /* Duplicate the lock so that the directory structure can't change
  64.      while we're doing this. */
  65.  
  66.   omask = syscall (SYS_sigsetmask, ~0);
  67.   fl = DupLock (lock);
  68.  
  69.   /* Follow the chain of directories and build the name in 'buffer' */
  70.  
  71.   while (fl != 0L)
  72.     {
  73.       if (Examine (fl, fib) == DOSFALSE)
  74.     {
  75.       errno = __ioerr_to_errno(IoErr());
  76.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  77.       UnLock (fl);
  78.       goto ret;
  79.     }
  80.       next_fl = ParentDir (fl);
  81.       UnLock (fl);
  82.       if (p != 0L)
  83.     {
  84.       if (next_fl != 0L)
  85.         *--p = '/';
  86.       else
  87.         *--p = ':';
  88.     }
  89.       else
  90.     {
  91.       p = buffer + buffer_length - 1;    /* fix 20-jan-92 ## mw */
  92.       *p = '\0';
  93.       if (next_fl == 0L)
  94.         *--p = ':';
  95.     }
  96.       length = strlen (fib->fib_FileName);
  97.       p -= length;
  98.       if (p <= buffer)
  99.     {
  100.       if (next_fl != 0L)
  101.         UnLock (next_fl);
  102.       goto ret;
  103.     }
  104.       bcopy (fib->fib_FileName, p, length);
  105.       fl = next_fl;
  106.     }
  107.  
  108.   /* Move the pathname so that it starts at buffer[0]. */
  109.  
  110.   bcopy (p, buffer, strlen (p) + 1);
  111.  
  112.   result = buffer;
  113.  
  114. ret:
  115.   syscall (SYS_sigsetmask, omask);
  116.   return result;
  117. }
  118.  
  119.  
  120. static char *
  121. _get_pwd (char *buffer, int buffer_length)
  122. {
  123.   struct Process *proc;
  124.   char *result, *colon;
  125.   extern char *index (const char *, int);
  126.  
  127.   proc = (struct Process *) FindTask (0L);
  128.  
  129.   /* Just return an empty string if this is not a process. */
  130.  
  131.   if (proc == 0L || proc->pr_Task.tc_Node.ln_Type != NT_PROCESS)
  132.     {
  133.       buffer[0] = '\0';
  134.       return buffer;
  135.     }
  136.  
  137.   /* make room for slash */
  138.   if (ix.ix_flags & ix_translate_slash)
  139.     buffer++;
  140.  
  141.   if (GetCurrentDirName (buffer, buffer_length) ||
  142.       NameFromLock (proc->pr_CurrentDir, buffer, buffer_length))
  143.     {
  144.       errno = 0;
  145.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  146.       result = buffer;
  147.       goto returnit;
  148.     }
  149.   /* and as the last chance resort to the 1.3 algorithm */
  150.  
  151.   result = _GetPathFromLock (proc->pr_CurrentDir, buffer, buffer_length);
  152.  
  153. returnit:
  154.   if ((ix.ix_flags & ix_translate_slash) && result)
  155.     {
  156.       colon = index (result, ':');
  157.       if (colon)
  158.         {
  159.       *colon = '/';
  160.           result--;
  161.           result[0] = '/';
  162.       return result;
  163.         }
  164.  
  165.        bcopy (result, result - 1, strlen (result) + 1);
  166.        return result - 1;
  167.     }
  168.  
  169.   return result;
  170. }
  171.  
  172.  
  173. char *
  174. getwd (char *buffer)
  175. {
  176.   char *path;
  177.  
  178.   path = _get_pwd (buffer, MAXPATHLEN);
  179.   if (path == 0L)
  180.     {
  181.       strcpy (buffer, "getwd - ");
  182.       strcat (buffer, strerror (errno));
  183.       return 0L;
  184.     }
  185.  
  186.   return path;
  187. }
  188.  
  189.  
  190. char *
  191. getcwd (char *buffer, size_t buffer_length)
  192. {
  193.  
  194.   if (buffer == 0L)
  195.     {
  196.       buffer = (char *) syscall (SYS_malloc, buffer_length + 2);
  197.       if (buffer == 0L)
  198.     {
  199.       errno = ENOMEM;
  200.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  201.       return 0L;
  202.     }
  203.     }
  204.  
  205.   return _get_pwd (buffer, buffer_length);
  206. }
  207.